#pragma once
/***********************************************************************************************
COPYRIGHT 2011 Mafahir Fairoze

This file is part of Neural++.
(Project Website : http://mafahir.wordpress.com/projects/neuralplusplus)

Neural++ is a free software. You can redistribute it and/or modify it under the terms of
the GNU General Public License as published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Neural++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License <http://www.gnu.org/licenses/> for more details.

***********************************************************************************************/
#include "../INeighborhoodFunction.h"
#include "../KohonenLayer.h"

namespace NeuralPlusPlus
	{
	namespace Core
		{
		namespace SOM
			{			
			namespace NeighborhoodFunctions      
				{
				/// <summary>
				/// Mexican Hat Neighborhood Function is the normalized second derivative of a Gaussian function.
				/// It is a continuous function with neighborhood value decreasing from unity at the winner to
				/// a negative value at a certain point (forming an inhibitory influence) and then gradually
				/// increasing to zero.
				/// </summary>
				class MexicanHatFunction : public INeighborhoodFunction
					{
					/* 
					*  Mexican Hat Function = a * (1 - ((x-b)/c)square) * Exp( - 1/2 * ((x-b)/c)square)
					*
					*  The parameter 'a' is the height of the curve's peak, 'b' is the position of the center of
					*  the peak, and 'c' controls the width of the bell shape.
					*
					*  For a Mexican Hat Neighborhood function,
					*  a = unity (the neighborhood at the winner)
					*  b = winner position
					*  c = depends on training progress.
					*
					*  Initial value of c is obtained from the user (as learning radius)
					*  Note that, (x-b)square denotes the euclidean distance between winner neuron 'b' and neuron 'x' 
					*
					*  (Mexican hat function) vs (Hamming distance)
					*                         _
					*                        / \
					*              _____    |   |    _____
					*                   \__/     \__/
					*                         .
					*                       Winner
					*/

					private: double Sigma;

							 /// <summary>
							 /// Creates a new Mexican Hat Neighborhood Function
							 /// </summary>
							 /// <param name="learningRadius">
							 /// Initial Learning Radius
							 /// </param>
					public: MexicanHatFunction(double learningRadius);

							/// <summary>
							/// Determines the neighborhood of every neuron in the given Kohonen layer with respect to
							/// winner neuron using Mexican Hat function
							/// </summary>
					public: void EvaluateNeighborhood(KohonenLayer *layer, int currentIteration, int trainingEpochs);
					};
				}
			}
		}
	}